package com.example.gokchinesefoodmapmcdev.filter;

import com.example.gokchinesefoodmapmcdev.exception.ValidateCodeException;
import com.example.gokchinesefoodmapmcdev.handler.MyLoginFailureHandler;
import com.example.gokchinesefoodmapmcdev.util.CacheUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义验证码过滤器
 * 需要继承OncePerRequestFilter确保在一次请求只通过一次filter，而不需要重复执行
 */
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {

    @Autowired
    private CacheUtils cacheUtils;

    @Autowired
    private MyLoginFailureHandler myLoginFailureHandler;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 1. 判断该请求是否为登录请求，如果是，则进行验证码校验操作
        if (request.getRequestURI().equals("/rest/app/authPassword") && request.getMethod().equalsIgnoreCase("post")) {
            try {
                validate(request);
            } catch (ValidateCodeException e) {
                myLoginFailureHandler.onAuthenticationFailure(request, response, e);
                return;
            }
        }
        // 不是就直接放行了
        filterChain.doFilter(request, response);
    }

    // 验证码校验
    private void validate(HttpServletRequest request) throws ValidateCodeException {
        //获取ip
        String remoteAddr = request.getRemoteAddr();

        // 从前端的cookies中得到标识，再从localCache中获取验证码
        String kaptcha = null;
        String uuid = null;
        Cookie[] cookies = request.getCookies();
        if (cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if ("kaptcha".equals(cookie.getName())) {
                    uuid = cookie.getValue();
                    kaptcha = cacheUtils.getLocalCache().getIfPresent(uuid);
                    break;
                }
            }
        }

        //获取用户提交的验证码
        String imageCode = request.getParameter("imageCode");

        if (!StringUtils.hasText(imageCode)) {
            throw new ValidateCodeException("验证码的值不能为空！");
        }
        if (kaptcha == null) {
            throw new ValidateCodeException("验证码已过期！");
        }
        if (!kaptcha.equalsIgnoreCase(imageCode)) {
            throw new ValidateCodeException("验证码不正确！");
        }
        // 验证码正确，将缓存中的验证码删除
        cacheUtils.getLocalCache().invalidate(uuid);
    }
}
